home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d13 / patch12.arc / TCPATCH3.DIF < prev    next >
Encoding:
Text File  |  1990-10-02  |  22.1 KB  |  716 lines

  1. TurboC2.0 Patches to enable ed scripts and fix TMP env var
  2. Prereq: 2
  3. *** tcpatlev.h    Wed Jul 18 10:37:44 1990
  4. --- tcpatlev.new    Wed Jul 18 10:38:10 1990
  5. ***************
  6. *** 1,1 ****
  7. ! #define TCPATCHLEVEL 2
  8. --- 1,1 ----
  9. ! #define TCPATCHLEVEL 3
  10. *** readme    Wed Jul 18 09:53:56 1990
  11. --- readme.new    Wed Jul 18 09:53:22 1990
  12. ***************
  13. *** 90,92 ****
  14. --- 90,165 ----
  15.   improved (more descriptive) usage message
  16.   temp files go in directory specified by TMP env var (or current dir if no TMP)
  17.   ed scripts still disabled
  18. + *** OFFICIAL PATCHLEVEL 12, TurboC2.0 PATCHLEVEL 3
  19. + Path: uwvax!ub.d.umn.edu!rutgers!usc!samsung!munnari.oz.au!bunyip!brolga!aas
  20. + From: aas@brolga.cc.uq.oz.au (Alex Sergejew)
  21. + Date: 15 Jul 90 11:03:51 GMT
  22. + The following are comments and patches to the patches to Larry Wall's patch
  23. + program (patchlevel 12) recently submitted by ward@sneezy.cs.wisc.edu
  24. + (Michael Ward) to allow compilation with Turbo C 2.0 and to run under MSDOS.
  25. + I have addressed a couple of recent bug reports and also re-enabled the
  26. + use of ed scripts (given a working MSDOS ed program, of which simtel20
  27. + has several that are compatible with unix V7 ed).
  28. + New files are:
  29. + popen    c      10579   7-15-90   3:58p
  30. + popen    h         69   3-08-88   8:08p
  31. + getswitc c        290   3-08-88   8:08p
  32. + popentst mak      303   7-15-90   3:43p
  33. + These provide the popen() functionality and were snarfed from simtel20
  34. + in `pd1:<msdos.turbo-c>popen.arc'.  The original author's name is not given.
  35. + Try `make -fpopentst' to check-out the DEMO mode (see popen.c) but
  36. + remember to delete popen.obj and getswitc.obj from this trial before
  37. + compiling the merged/patched version of patch.
  38. + Alex A Sergejew
  39. + University of Queensland Neuro-Psychiatric Institute
  40. + aas@cc.uq.oz.au
  41. + ---------------------------
  42. + weisen@eniac.seas.upenn.edu (Neil Weisenfeld) reports getting a run-time
  43. + error of the form:
  44. +     patch: couldn't create D:\/patchpxxxxxx
  45. + This is due to having the TMP environment variable set to "D:\"
  46. + (note that a lot of MSDOS software actually wants the trailing "\").
  47. + Patch as distributed blindly concatenates /patch?xxxxxx strings and the
  48. + "\/" juxtaposition causes strife to MSDOS.  The problem does not arise using
  49. + other shells such as ms_sh or ksh. A temporary workaround is to re-set the
  50. + TMP environment variable without the trailing "\".
  51. + This has been repaired in the appended patches.
  52. + ---------------------------
  53. + mlord@bwdls58.UUCP correctly observes that:
  54. + >>In file INP.C, there is a procedure called rev_in_string() at the bottom.
  55. + >>This procedure declares a local variable "s", which is then used without
  56. + >>first being given a value.  This instance of "s" should be replaced with
  57. + >>the parameter "string" instead on that one line.
  58. + This has also been repaired in the appended patches.
  59. + ---------------------------
  60. + There are still warnings reported by Turbo C in compiling the distribution:
  61. + In pch.c:
  62. + 243: Possible use of 'fcntl_line' before definition ...
  63. + the variable concerned is not in fact used before definition and the warning
  64. + can be safely ignored.
  65. + In popen.c there appear 3 warnings of the type:
  66. + xxx: 'lineno' is assigned a value which is never used in function ...
  67. + which can also be ignored (the variable is used in DEMO mode).
  68. + In util.c:
  69. + 177: possibly incorrect assignment ....
  70. + the message is misleading (see the Turbo C User Manual).
  71. +
  72. *** makefile    Sat Jun 02 16:13:34 1990
  73. --- makefile.new    Sun Jul 15 15:59:34 1990
  74. ***************
  75. *** 1,8 ****
  76.   CC = tcc
  77.   CFLAGS = -N -ml -DTURBOC20
  78.   
  79. ! c = patch.c pch.c inp.c version.c util.c
  80. ! obj = patch.obj pch.obj inp.obj util.obj version.obj
  81.   
  82.   .c.obj:
  83.       $(CC) -c $(CFLAGS) $(LARGE) $*.c
  84. --- 1,8 ----
  85.   CC = tcc
  86.   CFLAGS = -N -ml -DTURBOC20
  87.   
  88. ! c = patch.c pch.c inp.c version.c util.c popen.c getswitc.c
  89. ! obj = patch.obj pch.obj inp.obj version.obj util.obj popen.obj getswitc.obj
  90.   
  91.   .c.obj:
  92.       $(CC) -c $(CFLAGS) $(LARGE) $*.c
  93. ***************
  94. *** 12,18 ****
  95.   
  96.   patch.obj: config.h common.h patch.c inp.h pch.h util.h version.h
  97.   
  98. ! pch.obj: config.h common.h pch.c pch.h util.h
  99.   
  100.   inp.obj: config.h common.h inp.c inp.h util.h
  101.   
  102. --- 12,18 ----
  103.   
  104.   patch.obj: config.h common.h patch.c inp.h pch.h util.h version.h
  105.   
  106. ! pch.obj: config.h common.h pch.c pch.h util.h popen.h
  107.   
  108.   inp.obj: config.h common.h inp.c inp.h util.h
  109.   
  110. ***************
  111. *** 19,21 ****
  112. --- 19,25 ----
  113.   util.obj: config.h common.h util.c util.h
  114.   
  115.   version.obj: config.h common.h version.c version.h patchlevel.h util.h
  116. + popen.obj: popen.c popen.h
  117. + getswitc.obj: getswitc.c
  118. *** inp.c    Sun Jul 15 12:41:14 1990
  119. --- inp.new    Sun Jul 15 13:50:30 1990
  120. ***************
  121. *** 1,6 ****
  122. ! /* $Header: inp.c,v 2.0.1.2 90/05/30 11:30:00 mward $
  123.    *
  124.    * $Log:    inp.c,v $
  125.    * Revision 2.0.1.2  90/05/30  11:30:00 mward
  126.    * if TURBOC20 have plan_a check against MAXMEMBLK before mallocs
  127.    * if TURBOC20 have plan_b use binary mode io for tmp file
  128. --- 1,10 ----
  129. ! /* $Header: inp.c,v 2.0.1.3 90/07/15 13:52:00 aas $
  130.    *
  131.    * $Log:    inp.c,v $
  132. +  * Revision 2.0.1.3  90/07/15  13:52:00 aas
  133. +  * include bugfix reported by mlord@bwdls58.bnr.ca in rev_in_string()
  134. +  * regarding parameter string[] typo in first strnEQ() line
  135. +  *
  136.    * Revision 2.0.1.2  90/05/30  11:30:00 mward
  137.    * if TURBOC20 have plan_a check against MAXMEMBLK before mallocs
  138.    * if TURBOC20 have plan_b use binary mode io for tmp file
  139. ***************
  140. *** 323,329 ****
  141.       if (revision == Nullch)
  142.       return TRUE;
  143.       patlen = strlen(revision);
  144. !     if (strnEQ(string,revision,patlen) && isspace(s[patlen]))
  145.       return TRUE;
  146.       for (s = string; *s; s++) {
  147.       if (isspace(*s) && strnEQ(s+1, revision, patlen) && 
  148. --- 327,333 ----
  149.       if (revision == Nullch)
  150.       return TRUE;
  151.       patlen = strlen(revision);
  152. !     if (strnEQ(string,revision,patlen) && isspace(string[patlen]))
  153.       return TRUE;
  154.       for (s = string; *s; s++) {
  155.       if (isspace(*s) && strnEQ(s+1, revision, patlen) && 
  156. *** patch.c    Sun Jul 15 12:46:42 1990
  157. --- patch.new    Sun Jul 15 14:02:18 1990
  158. ***************
  159. *** 1,5 ****
  160.   char rcsid[] =
  161. !     "$Header: patch.c,v 2.0.1.7 90/05/30 11:30:00 mward $";
  162.   
  163.   /* patch - a program to apply diffs to original files
  164.    *
  165. --- 1,5 ----
  166.   char rcsid[] =
  167. !     "$Header: patch.c,v 2.0.1.8 90/07/15 14:00:00 aas $";
  168.   
  169.   /* patch - a program to apply diffs to original files
  170.    *
  171. ***************
  172. *** 9,14 ****
  173. --- 9,17 ----
  174.    * money off of it, or pretend that you wrote it.
  175.    *
  176.    * $Log:    patch.c,v $
  177. +  * Revision 2.0.1.7  90/07/15  14:00:00  aas
  178. +  * made init temp file names a little more MS-DOS aware
  179. +  *
  180.    * Revision 2.0.1.7  90/05/30  11:30:00  mward
  181.    * Added usage message vars and routines: use_msg, progname, usage, fname
  182.    * Check environment for TMP and init temp file names
  183. ***************
  184. *** 206,212 ****
  185.       int i;
  186.       char tmpdir[MAXPATH];
  187.       char *tmpenv;
  188.   
  189.       progname = (*argv[0]?argv[0]:"patch");
  190.       setbuf(stderr, serrbuf);
  191. --- 209,215 ----
  192.       int i;
  193.       char tmpdir[MAXPATH];
  194.       char *tmpenv;
  195. !     char c;
  196.   
  197.       progname = (*argv[0]?argv[0]:"patch");
  198.       setbuf(stderr, serrbuf);
  199. ***************
  200. *** 216,222 ****
  201.       /* initialize temp file names */
  202.       tmpenv = getenv("TMP");
  203.       strcpy(tmpdir,(tmpenv!=NULL?tmpenv:""));
  204. !     if (strlen(tmpdir) && tmpdir[strlen(tmpdir)-1]!='/') strcat(tmpdir,"/");
  205.       TMPOUTNAME = strcat(strcpy(malloc(MAXPATH),tmpdir),fname(TMPOUTNAME));
  206.       TMPINNAME  = strcat(strcpy(malloc(MAXPATH),tmpdir),fname(TMPINNAME));
  207.       TMPREJNAME = strcat(strcpy(malloc(MAXPATH),tmpdir),fname(TMPREJNAME));
  208. --- 219,227 ----
  209.       /* initialize temp file names */
  210.       tmpenv = getenv("TMP");
  211.       strcpy(tmpdir,(tmpenv!=NULL?tmpenv:""));
  212. !     if (strlen(tmpdir))
  213. !     if((c=tmpdir[strlen(tmpdir)-1])!='/' && c!='\\')
  214. !         strcat(tmpdir,"/");
  215.       TMPOUTNAME = strcat(strcpy(malloc(MAXPATH),tmpdir),fname(TMPOUTNAME));
  216.       TMPINNAME  = strcat(strcpy(malloc(MAXPATH),tmpdir),fname(TMPINNAME));
  217.       TMPREJNAME = strcat(strcpy(malloc(MAXPATH),tmpdir),fname(TMPREJNAME));
  218. *** pch.c    Sun Jul 15 12:41:50 1990
  219. --- pch.new    Sun Jul 15 15:23:00 1990
  220. ***************
  221. *** 1,6 ****
  222. ! /* $Header: pch.c,v 2.0.1.7 90/05/30 11:30:00 mward $
  223.    *
  224.    * $Log:    pch.c,v $
  225.    * Revision 2.0.1.8  90/05/30  11:30:00  mward
  226.    * replace do_ed_script with stub
  227.    * modify calls to read, write to detect error on return value of -1
  228. --- 1,9 ----
  229. ! /* $Header: pch.c,v 2.0.1.9 90/07/15 15:27:00 aas $
  230.    *
  231.    * $Log:    pch.c,v $
  232. +  * Revision 2.0.1.9  90/07/15  15:27:00  aas
  233. +  * put do_ed_script() back the way it was and slot-in MSDOS popen/pclose
  234. +  *
  235.    * Revision 2.0.1.8  90/05/30  11:30:00  mward
  236.    * replace do_ed_script with stub
  237.    * modify calls to read, write to detect error on return value of -1
  238. ***************
  239. *** 38,43 ****
  240. --- 41,49 ----
  241.   #include "util.h"
  242.   #include "INTERN.h"
  243.   #include "pch.h"
  244. + #ifdef TURBOC20
  245. + #include "popen.h"
  246. + #endif
  247.   
  248.   /* Patch (diff listing) abstract type. */
  249.   
  250. ***************
  251. *** 1062,1077 ****
  252.       return p_hunk_beg;
  253.   }
  254.   
  255. - #ifdef TURBOC20 
  256. - /* Ignore an ed script. */
  257. - void
  258. - do_ed_script()
  259. - {
  260. -     say1("Sorry, can't do ed scripts yet!\n");
  261. -     say1("Use ed to do this one yourself!\n");
  262. - }
  263. - #else
  264.   /* Apply an ed script by feeding ed itself. */
  265.   
  266.   void
  267. --- 1068,1073 ----
  268. ***************
  269. *** 1086,1095 ****
  270. --- 1082,1095 ----
  271.       if (!skip_rest_of_patch) {
  272.       Unlink(TMPOUTNAME);
  273.       copy_file(filearg[0], TMPOUTNAME);
  274. + #ifdef TURBOC20
  275. +     Sprintf(buf, "ed %s", TMPOUTNAME);
  276. + #else
  277.       if (verbose)
  278.           Sprintf(buf, "/bin/ed %s", TMPOUTNAME);
  279.       else
  280.           Sprintf(buf, "/bin/ed - %s", TMPOUTNAME);
  281. + #endif
  282.       pipefp = popen(buf, "w");
  283.       }
  284.       for (;;) {
  285. ***************
  286. *** 1135,1138 ****
  287.       chmod(outname, filemode);
  288.       set_signals(1);
  289.   }
  290. ! #endif
  291. --- 1135,1138 ----
  292.       chmod(outname, filemode);
  293.       set_signals(1);
  294.   }
  295. *** /dev/null
  296. --- popen.h    Tue Mar 08 20:08:36 1988
  297. ***************
  298. *** 0 ****
  299. --- 1,2 ----
  300. + extern FILE *popen( char *, char * );
  301. + extern int pclose( FILE * );
  302. *** /dev/null
  303. --- popen.c    Sun Jul 15 15:58:08 1990
  304. ***************
  305. *** 0 ****
  306. --- 1,339 ----
  307. + /* popen/pclose:
  308. +  *
  309. +  * simple MS-DOS piping scheme to imitate UNIX pipes
  310. +  *
  311. +  * $Log:    popen.c,v $
  312. +  * Revision 1.0.1  90/07/15  14:05:00  aas
  313. +  * fix assumption of trailing "/" in popen()
  314. +  *
  315. +  * Revision 1.0.0  88/08/03  20:08:00  ???
  316. +  * original distribution: author unknown
  317. +  * found on simtel20 as pd1:<msdos.turbo-c>popen.arc
  318. +  *
  319. +  */
  320. + #include <stdio.h>
  321. + #include <ctype.h>
  322. + #include <alloc.h>
  323. + #include <string.h>
  324. + #include <errno.h>
  325. + #include <setjmp.h>
  326. + #include <process.h>
  327. + #include "popen.h"
  328. + extern char *getenv( char * );
  329. + #ifndef    _NFILE
  330. + # define    _NFILE    OPEN_MAX    /* Number of open files */
  331. + #endif    _NFILE
  332. + #define READIT    1            /* Read pipe */
  333. + #define WRITEIT    2            /* Write pipe */
  334. + static char *prgname[ _NFILE ];        /* program name if write pipe */
  335. + static int pipetype[ _NFILE ];        /* 1=read 2=write */
  336. + static char *pipename[ _NFILE ];    /* pipe file name */
  337. + /*
  338. +  *------------------------------------------------------------------------
  339. +  * stoupper: Convert string to uppercase (in place)
  340. +  *------------------------------------------------------------------------
  341. +  */
  342. + static void
  343. + stoupper( s )
  344. + char *s;
  345. + {
  346. +    int c;
  347. +    for( ; (c = *s) != '\0'; ++s ) {
  348. +       if( islower( c ) ) *s = _toupper( c );
  349. +    }
  350. + }
  351. + /*
  352. +  *------------------------------------------------------------------------
  353. +  * strsave: Copy string into malloc'ed memory and return address
  354. +  *------------------------------------------------------------------------
  355. +  */
  356. +  
  357. + static char *
  358. + strsave( s )
  359. + char *s;
  360. + {
  361. +    char *sp = malloc( strlen( s ) + 1 );
  362. +    if( sp != (char *) NULL ) (void) strcpy( sp, s );
  363. +    return( sp );
  364. + }
  365. + /*
  366. +  *------------------------------------------------------------------------
  367. +  * strfree: Returm strsave'd string memory
  368. +  *------------------------------------------------------------------------
  369. +  */
  370. + static void
  371. + strfree( s )
  372. + char *s;
  373. + {
  374. +    if( s != (char *) NULL ) free( s );
  375. + }
  376. + /*
  377. +  *------------------------------------------------------------------------
  378. +  * run: Execute command via SHELL or COMSPEC
  379. +  *------------------------------------------------------------------------
  380. +  */
  381. + static int
  382. + run( command )
  383. + char *command;
  384. + {
  385. +    jmp_buf panic;            /* How to recover from errors */
  386. +    int lineno;                /* Line number where panic happened */
  387. +    char *shell;                /* Command processor */
  388. +    char *s = (char *) NULL;        /* Holds the command */
  389. +    int s_is_malloced = 0;        /* True if need to free 's' */
  390. +    static char *command_com = "COMMAND.COM";
  391. +    int status;                /* Return codes */
  392. +    char *shellpath;            /* Full command processor path */
  393. +    char *bp;                /* Generic string pointer */
  394. +    static char dash_c[ 3 ] = { '?', 'c', '\0' };
  395. +    if( (lineno = setjmp( panic )) != 0 ) {
  396. +       int E = errno;
  397. + #ifdef    DEMO
  398. +       fprintf( stderr, "RUN panic on line %d: %d\n", lineno, E );
  399. + #endif    DEMO
  400. +       if( s_is_malloced && (s != (char *) NULL) ) strfree( s );
  401. +       errno = E;
  402. +       return( -1 );
  403. +    }
  404. +    if( (s = strsave( command )) == (char *) NULL ) longjmp( panic, __LINE__ );
  405. +    /* Determine the command processor */
  406. +    if( ((shell = getenv( "SHELL" )) == (char *) NULL) &&
  407. +        ((shell = getenv( "COMSPEC" )) == (char *) NULL) ) shell = command_com;
  408. +    stoupper( shell );
  409. +    shellpath = shell;
  410. +    /* Strip off any leading backslash directories */
  411. +    shell = strrchr( shellpath, '\\' );
  412. +    if( shell != (char *) NULL ) ++shell;
  413. +    else                         shell = shellpath;
  414. +    /* Strip off any leading slash directories */
  415. +    bp = strrchr( shell, '/'  );
  416. +    if( bp != (char *) NULL ) shell = ++bp;
  417. +    if( strcmp( shell, command_com ) != 0 ) {
  418. +       /* MKS Shell needs quoted argument */
  419. +       char *bp;
  420. +       if( (bp = s = malloc( strlen( command ) + 3 )) == (char *) NULL ) 
  421. +      longjmp( panic, __LINE__ );
  422. +       *bp++ = '\'';
  423. +       while( (*bp++ = *command++) != '\0' );
  424. +       *(bp - 1) = '\'';
  425. +       *bp = '\0';
  426. +       s_is_malloced = 1;
  427. +    } else s = command;
  428. +    dash_c[ 0 ] = getswitch();
  429. +    /* Run the program */
  430. + #ifdef    DEMO
  431. +    fprintf( stderr, "Running: (%s) %s %s %s\n", shellpath, shell, dash_c, s );
  432. + #endif    DEMO
  433. +    status = spawnl( P_WAIT, shellpath, shell, dash_c, s, (char *) NULL );
  434. +    if( s_is_malloced ) free( s );
  435. +    return( status );
  436. + }
  437. + /* 
  438. +  *------------------------------------------------------------------------
  439. +  * uniquepipe: returns a unique file name 
  440. +  *------------------------------------------------------------------------
  441. +  */
  442. + static char *
  443. + uniquepipe()
  444. + { 
  445. +    static char name[ 14 ];
  446. +    static short int num = 0;
  447. +    (void) sprintf( name, "pipe%05d.tmp", num++ );
  448. +    return( name );
  449. + }
  450. + /*
  451. +  *------------------------------------------------------------------------
  452. +  * resetpipe: Private routine to cancel a pipe
  453. +  *------------------------------------------------------------------------
  454. +  */
  455. + static void
  456. + resetpipe( fd )
  457. + int fd;
  458. + {
  459. +    char *bp;
  460. +    if( (fd >= 0) && (fd < _NFILE) ) {
  461. +       pipetype[ fd ] = 0;
  462. +       if( (bp = pipename[ fd ]) != (char *) NULL ) {
  463. +      (void) unlink( bp );
  464. +      strfree( bp );
  465. +      pipename[ fd ] = (char *) NULL;
  466. +       }
  467. +       if( (bp = prgname[ fd ]) != (char *) NULL ) {
  468. +      strfree( bp );
  469. +      prgname[ fd ] = (char *) NULL;
  470. +       }
  471. +    }
  472. + }
  473. + /* 
  474. +  *------------------------------------------------------------------------
  475. +  * popen: open a pipe 
  476. +  *------------------------------------------------------------------------
  477. +  */
  478. + FILE *popen( prg, type )
  479. + char *prg;            /* The command to be run */
  480. + char *type;            /* "w" or "r" */
  481. + { 
  482. +    FILE *p = (FILE *) NULL;    /* Where we open the pipe */
  483. +    int ostdin;            /* Where our stdin is now */
  484. +    int pipefd = -1;        /* fileno( p ) -- for convenience */
  485. +    char tmpfile[ BUFSIZ ];    /* Holds name of pipe file */
  486. +    char *tmpdir;        /* Points to directory prefix of pipe */
  487. +    jmp_buf panic;        /* Where to go if there's an error */
  488. +    int lineno;            /* Line number where panic happened */
  489. +    char c;                            /* aas */
  490. +    /* Find out where we should put temporary files */
  491. +    if( (tmpdir = getenv( "TMPDIR" )) == (char *) NULL ) 
  492. +       tmpdir = getenv( "TMP" );
  493. +    if( tmpdir != (char *) NULL ) {
  494. +       /* Use temporary directory if available */
  495. +       (void) strcpy( tmpfile, tmpdir );
  496. +       if((c=tmpfile[strlen(tmpfile)-1])!='/' && c!='\\')    /* aas */
  497. +      (void) strcat( tmpfile, "/" );
  498. +    } else *tmpfile = '\0';
  499. +    /* Get a unique pipe file name */
  500. +    (void) strcat( tmpfile, uniquepipe() );
  501. +    if( (lineno = setjmp( panic )) != 0 ) {
  502. +       /* An error has occurred, so clean up */
  503. +       int E = errno;
  504. + #ifdef    DEMO
  505. +       fprintf( stderr, "POPEN panic on line %d: %d\n", lineno, E );
  506. + #endif    DEMO
  507. +       if( p != (FILE *) NULL ) (void) fclose( p );
  508. +       resetpipe( pipefd );
  509. +       errno = E;
  510. +       return( (FILE *) NULL );
  511. +    }
  512. +    if( strcmp( type, "w" ) == 0 ) {
  513. +       /* for write style pipe, pclose handles program execution */
  514. +       if( (p = fopen( tmpfile, "w" )) != (FILE *) NULL ) {
  515. +      pipefd = fileno( p );
  516. +      pipetype[ pipefd ] = WRITEIT;
  517. +      pipename[ pipefd ] = strsave( tmpfile );
  518. +      prgname[ pipefd ]  = strsave( prg );
  519. +      if( !pipename[ pipefd ] || !prgname[ pipefd ] ) longjmp( panic, __LINE__ );
  520. +       }
  521. +    } else if( strcmp( type, "r" ) == 0 ) {
  522. +       /* read pipe must create tmp file, set up stdout to point to the temp
  523. +       * file, and run the program.  note that if the pipe file cannot be
  524. +       * opened, it'll return a condition indicating pipe failure, which is
  525. +       * fine.
  526. +       */
  527. +       if( (p = fopen( tmpfile, "w" )) != (FILE *) NULL ) {
  528. +      int ostdout;
  529. +      pipefd = fileno( p );
  530. +      pipetype[ pipefd ]= READIT;
  531. +      if( (pipename[ pipefd ] = strsave( tmpfile )) == (char *) NULL ) 
  532. +         longjmp( panic, __LINE__ );
  533. +      /* Redirect stdin for the new command */
  534. +      ostdout = dup( fileno( stdout ) );
  535. +      if( dup2( fileno( stdout ), pipefd ) < 0 ) {
  536. +         int E = errno;
  537. +         (void) dup2( fileno( stdout ), ostdout );
  538. +         errno = E;
  539. +         longjmp( panic, __LINE__ );
  540. +      }
  541. +      if( run( prg ) != 0 ) longjmp( panic, __LINE__ );
  542. +      if( dup2( fileno( stdout ), ostdout ) < 0 ) longjmp( panic, __LINE__ );
  543. +      if( fclose( p ) < 0 ) longjmp( panic, __LINE__ );
  544. +      if( (p = fopen( tmpfile, "r" )) == (FILE *) NULL ) longjmp( panic, __LINE__ );
  545. +       }
  546. +    } else {
  547. +       /* screwy call or unsupported type */
  548. +       errno = EINVFNC;
  549. +       longjmp( panic, __LINE__ );
  550. +    }
  551. +    return( p );
  552. + }
  553. + /* close a pipe */
  554. + int
  555. + pclose( p )
  556. + FILE *p;
  557. + {
  558. +    int pipefd = -1;        /* Fildes where pipe is opened */
  559. +    int ostdout;            /* Where our stdout points now */
  560. +    int ostdin;            /* Where our stdin points now */
  561. +    jmp_buf panic;        /* Context to return to if error */
  562. +    int lineno;            /* Line number where panic happened */
  563. +    if( (lineno = setjmp( panic )) != 0 ) {
  564. +       /* An error has occurred, so clean up and return */
  565. +       int E = errno;
  566. + #ifdef    DEMO
  567. +       fprintf( stderr, "POPEN panic on line %d: %d\n", lineno, E );
  568. + #endif    DEMO
  569. +       if( p != (FILE *) NULL ) (void) fclose( p );
  570. +       resetpipe( pipefd );
  571. +       errno = E;
  572. +       return( -1 );
  573. +    }
  574. +    pipefd = fileno( p );
  575. +    if( fclose( p ) < 0 ) longjmp( panic, __LINE__ );
  576. +    switch( pipetype[ pipefd ] ) {
  577. +       case WRITEIT:
  578. +      /* open the temp file again as read, redirect stdin from that
  579. +       * file, run the program, then clean up.
  580. +       */
  581. +       if( (p = fopen( pipename[ pipefd ],"r" )) == (FILE *) NULL ) 
  582. +      longjmp( panic, __LINE__ );
  583. +       ostdin = dup( fileno( stdin ));
  584. +       if( dup2( fileno( stdin ), fileno( p ) ) < 0 ) longjmp( panic, __LINE__ );
  585. +       if( run( prgname[ pipefd ] ) != 0 ) longjmp( panic, __LINE__ );
  586. +       if( dup2( fileno( stdin ), ostdin ) < 0 ) longjmp( panic, __LINE__ );
  587. +       if( fclose( p ) < 0 ) longjmp( panic, __LINE__ );
  588. +       resetpipe( pipefd );
  589. +       break;
  590. +    case READIT:
  591. +       /* close the temp file and remove it */
  592. +       resetpipe( pipefd );
  593. +       break;
  594. +    default:
  595. +       errno = EINVFNC;
  596. +       longjmp( panic, __LINE__ );
  597. +       /*NOTREACHED*/
  598. +    }
  599. +    return( 0 );
  600. + }
  601. + #ifdef    DEMO
  602. + int
  603. + main( argc, argv )
  604. + int argc;
  605. + char **argv;
  606. + {
  607. +    FILE *pipe;
  608. +    char buf[ BUFSIZ ];
  609. +    int n;
  610. +    *buf = '\0';
  611. +    for( n = 1; n < argc; ++n ) {
  612. +       (void) strcat( buf, argv[ n ] );
  613. +       (void) strcat( buf, " " );
  614. +    }
  615. +    if( (pipe = popen( buf, "r" )) != (FILE *) NULL ) {
  616. +       while( fgets( buf, sizeof( buf ), pipe ) != (char *) NULL ) 
  617. +      (void) fputs( buf, stdout );
  618. +       if( pclose( pipe ) != 0 ) fprintf( stderr, "error closing pipe!\n" );
  619. +    } else fprintf( stderr, "it didn't work!\n" );
  620. +    exit( 0 );
  621. +    /*NOTREACHED*/
  622. + }
  623. + #endif    DEMO
  624. *** /dev/null
  625. --- getswitc.c    Tue Mar 08 20:08:04 1988
  626. ***************
  627. *** 0 ****
  628. --- 1,16 ----
  629. + #include <stdio.h>
  630. + #include <dos.h>
  631. +  
  632. + static    char    SW = 0;        /* DOS switch character, either '-' or '/' */
  633. + int
  634. + getswitch()
  635. + {
  636. +    if (SW == 0) {
  637. +       /* get SW using dos call 0x37 */
  638. +       _AX = 0x3700;
  639. +       geninterrupt(0x21);
  640. +       SW = _DL;
  641. +    }
  642. +    return( SW & 0xFF );
  643. + }
  644. *** /dev/null
  645. --- popentst.mak    Sun Jul 15 15:43:08 1990
  646. ***************
  647. *** 0 ****
  648. --- 1,18 ----
  649. + popen.exe: popen.obj getswitch.obj
  650. +     tcc -epopen popen.obj getswitch.obj
  651. + popen.obj: popen.c popen.h
  652. +     tcc -c -DDEMO popen.c
  653. + getswitch.obj: getswitch.c
  654. +     tcc -c getswitch.c
  655. + clean:
  656. +     rm -f *.obj core *.map
  657. + clobber: clean
  658. +     rm -f *.exe install
  659. +     
  660. + install:
  661. +     tcc -c popen.c
  662. +     @echo What next?
  663.  
  664.  
  665.